import { cloneDeep } from 'lodash';
import { defineStore } from 'pinia';
import { getToken, removeToken, setToken } from '../utils/token-utils';
import type { UserInfoState } from './interface';
import {staticRoutes, allAsyncRoutes, anyRoute} from '@/router/routes'
import { getUserInfoApi, loginApi, logoutApi } from '@/api/acl/login';
import router from '@/router';
import type { RouteRecordRaw } from 'vue-router';


/* 
对所有的异步路由进行过滤得到用户的权限路由表
*/
function filterAsyncRoutes(allAsyncRoutes: RouteRecordRaw[], routeNames: string[]):  RouteRecordRaw[]{

  return allAsyncRoutes.filter(route => {
    // 如果route的name没有在routeNames中, 过滤它(返回false)
    if (!routeNames.includes(route.name as string)) return false

    // 如果当前route有子路由, 需要子路由进行递归过滤
    if (route.children && route.children.length>0) {
      route.children = filterAsyncRoutes(route.children, routeNames)   // 一定要对children进行重新赋值
    }

    // 否则返回true
    return true
  })
}

// 注册指定的路由表
function addRoutes(routes: RouteRecordRaw[]) {
  routes.forEach(route => router.addRoute(route))
}

// 重置路由  只注册静态的初始路由
function resetRoute() {
  // 得到所有已经注册的路由, 根据路由的name进行删除
  router.getRoutes().forEach(route => route.name && router.removeRoute(route.name))
  // 重新注册静态路由
  // staticRoutes.forEach(route => router.addRoute(route))
  addRoutes(staticRoutes)
}



/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore('userInfo', {

	state: (): UserInfoState => ({
    token: getToken() as string,
    name: '',
    avatar: '',
    menuRoutes: [], // 用于生成导航菜单的路由表
    buttons: [],
    roles: []
  }),

	actions: {
    // 登陆的异步action
    async login (username: string, password: string) {

      // 发送登陆的请求
      const result = await loginApi(username, password)
      // 请求成功后, 取出token保存  pinia和local中
      const token = result.token
      this.token = token
      setToken(token)
    },

    async getInfo () {
      // 请求获取用户信息
      const result = await getUserInfoApi()
      // 请求成功后, 读取用户信息name和avatar, 保存到state
      const {name, avatar, routes, buttons, roles} = result
      this.name = name
      this.avatar = avatar

      // 保存按钮权限列表和角色列表
      this.buttons = buttons
      this.roles = roles

      // 根据路由权限数据routes从allAsyncRoutes过滤出用户权限路由表, 进行动态注册
      const asyncRoutes = filterAsyncRoutes(cloneDeep(allAsyncRoutes), routes)
      // asyncRoutes.forEach(route => {
      //   router.addRoute(route)
      // });
      // router.addRoute(anyRoute) // 最后注册通配路由
      addRoutes([...asyncRoutes, anyRoute])

      // 根据静态路由表+用户权限路由表合并生成权限导航菜单
      this.menuRoutes = [...staticRoutes, ...asyncRoutes]
    },

    async reset () {

      // 如果当前有用户名, 请求退出登陆接口
      if (this.name) {
        await logoutApi() // 加await后, 下面的代码是在请求成功后执行的
      }

      // 删除local中保存的token
      removeToken()
      // 提交重置用户信息的mutation
      this.token = ''
      this.name = ''
      this.avatar = ''

      this.menuRoutes = [] // 清空菜单路由列表
      this.buttons = [] // 按钮权限列表
      // 重置注册的路由 => 只注册静态路由, 清除动态注册的路由
      resetRoute()
    },
	},
});
